package com.example.audiostreaming.implement;

import android.content.Context;
import android.content.SharedPreferences;
import android.widget.Toast;

import com.example.audiostreaming.base.BaseApplication;
import com.example.audiostreaming.data.XimalayApi;
import com.example.audiostreaming.interfaces.IPlayerLogic;
import com.example.audiostreaming.interfaces.IPlayerViewCallback;
import com.example.audiostreaming.utils.UtilLog;
import com.ximalaya.ting.android.opensdk.datatrasfer.IDataCallBack;
import com.ximalaya.ting.android.opensdk.model.PlayableModel;
import com.ximalaya.ting.android.opensdk.model.advertis.Advertis;
import com.ximalaya.ting.android.opensdk.model.advertis.AdvertisList;
import com.ximalaya.ting.android.opensdk.model.track.Track;
import com.ximalaya.ting.android.opensdk.model.track.TrackList;
import com.ximalaya.ting.android.opensdk.player.XmPlayerManager;
import com.ximalaya.ting.android.opensdk.player.advertis.IXmAdsStatusListener;
import com.ximalaya.ting.android.opensdk.player.constants.PlayerConstants;
import com.ximalaya.ting.android.opensdk.player.service.IXmPlayerStatusListener;
import com.ximalaya.ting.android.opensdk.player.service.XmPlayListControl;
import com.ximalaya.ting.android.opensdk.player.service.XmPlayerException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import static com.example.audiostreaming.base.BaseApplication.getAppContext;
import static com.ximalaya.ting.android.opensdk.player.service.XmPlayListControl.PlayMode.PLAY_MODEL_LIST_LOOP;
import static com.ximalaya.ting.android.opensdk.player.service.XmPlayListControl.PlayMode.PLAY_MODEL_RANDOM;
import static com.ximalaya.ting.android.opensdk.player.service.XmPlayListControl.PlayMode.PLAY_MODEL_SINGLE_LOOP;

public class ImplPlayerLogic implements IPlayerLogic {
    private static final String TAG = "ImplPlayerLogic";
    private final SharedPreferences mPlayModeSp;//播放模式持久化
    private List<IPlayerViewCallback> mIPlayerViewCallbacks = new ArrayList<>();//回调过来的视图
    private  XmPlayerManager mPlayerManager;
    private Track mCurrentTrack;
    public static final int DEFAULT_PLAY_INDEX = 0;
    private int mCurrentIndex=DEFAULT_PLAY_INDEX;
    private boolean mIsReverse = false;

    //sp's key and name
    public static final String PLAY_MODE_SP_NAME = "PlayMod";
    public static final String PLAY_MODE_SP_KEY = "currentPlayMode";
    public static final int PLAY_MODEL_LIST_LOOP_INT = 0;
    public static final int PLAY_MODEL_RANDOM_INT = 1;
    public static final int PLAY_MODEL_SINGLE_LOOP_INT = 2;
    private XmPlayListControl.PlayMode mCurrentPlayMode= XmPlayListControl.PlayMode.PLAY_MODEL_LIST_LOOP;;
    private int mCurrentProgressPosition=0;
    private int mCurrentProgressDuration=0;

    private ImplPlayerLogic(){
        mPlayerManager = XmPlayerManager.getInstance(getAppContext());
        mPlayerManager.addAdsStatusListener(new MyIXmAdsStatusListener() );//注册广告状态监听器
        mPlayerManager.addPlayerStatusListener(new MyIXmPlayerStatusListener());//注册播放器状态监听器
        //记录当前的播放模式，数据持久化
        mPlayModeSp = BaseApplication.getAppContext().getSharedPreferences(PLAY_MODE_SP_NAME, Context.MODE_PRIVATE);
    }
    private static ImplPlayerLogic sInstanceImplPlayerLogic = null;
    /**
     * 懒汉式单例模式
     * @return 单例对象
     */
    public static ImplPlayerLogic getInstanceImplPlayerLogic(){
        if (sInstanceImplPlayerLogic ==null) {
            synchronized (ImplPlayerLogic.class){//防止多线程
                if (sInstanceImplPlayerLogic ==null) {
                    sInstanceImplPlayerLogic = new ImplPlayerLogic();
                }
            }
        }
        return sInstanceImplPlayerLogic;
    }


    private boolean isSetPlayListData = false;
    public void setPlayListData(List<Track> playListData,int playIndex){
        if (mPlayerManager != null) {
            mPlayerManager.setPlayList(playListData,playIndex);
            isSetPlayListData = true;
            mCurrentTrack = playListData.get(playIndex);
            mCurrentIndex = playIndex;
        }else {
            UtilLog.d(TAG,"mPlayerManager为空");
        }
    }

    @Override
    public void play() {
        if (isSetPlayListData) {
            if (mPlayerManager != null) {
                mPlayerManager.play();
            }
        }
    }

    @Override
    public void pause() {
        if (isSetPlayListData) {
            if (mPlayerManager != null) {
                mPlayerManager.pause();
            }
        }
    }

    @Override
    public void stop() {

    }

    @Override
    public void playPre() {
        if (mPlayerManager != null) {
            mPlayerManager.playPre();
        }
    }

    @Override
    public void playNext() {
        if (mPlayerManager != null) {
            mPlayerManager.playNext();
        }
    }

    @Override
    public void switchPlayMode(XmPlayListControl.PlayMode mode) {
        if(mPlayerManager != null) {
            mCurrentPlayMode = mode;
            mPlayerManager.setPlayMode(mode);
            //通知UI更新播放模式
            if (mIPlayerViewCallbacks != null) {
                for (IPlayerViewCallback iPlayerViewCallback : mIPlayerViewCallbacks) {
                    iPlayerViewCallback.onPlayModeChange(mode);
                }
                //保存到sp里头去。
                SharedPreferences.Editor edit = mPlayModeSp.edit();
                edit.putInt(PLAY_MODE_SP_KEY,getIntByPlayMode(mode));
                edit.commit();
            }
        }
    }

    private int getIntByPlayMode(XmPlayListControl.PlayMode mode) {
        switch(mode) {
            case PLAY_MODEL_LIST_LOOP:
                return PLAY_MODEL_LIST_LOOP_INT;
            case PLAY_MODEL_RANDOM:
                return PLAY_MODEL_RANDOM_INT;
            case PLAY_MODEL_SINGLE_LOOP:
                return PLAY_MODEL_SINGLE_LOOP_INT;
        }
        return PLAY_MODEL_LIST_LOOP_INT;
    }
    private XmPlayListControl.PlayMode getModeByInt(int index) {
        switch(index) {
            case PLAY_MODEL_LIST_LOOP_INT:
                return PLAY_MODEL_LIST_LOOP;
            case PLAY_MODEL_RANDOM_INT:
                return PLAY_MODEL_RANDOM;
            case PLAY_MODEL_SINGLE_LOOP_INT:
                return PLAY_MODEL_SINGLE_LOOP;
        }
        return PLAY_MODEL_LIST_LOOP;
    }

    @Override
    public void getPlayListData() {
        if (mPlayerManager != null) {
            List<Track> playList = mPlayerManager.getPlayList();
            if (mIPlayerViewCallbacks != null) {
                for (IPlayerViewCallback iPlayerViewCallback : mIPlayerViewCallbacks) {
                    iPlayerViewCallback.onListLoaded(playList);
                }
            }
        }
    }

    @Override
    public void playByIndex(int index) {
        //切换播放器到第index的位置进行播放
        if (mPlayerManager != null) {
            mPlayerManager.play(index);
        }
    }

    @Override
    public void seekTo(int progress) {
        //更新拖动后的进度条进度
        if (mPlayerManager != null) {
            mPlayerManager.seekTo(progress);
        }
    }


    @Override
    public boolean isPlaying() {
        return  mPlayerManager.isPlaying();//返回当前是否正在播放
    }

    @Override
    public void reversePlayList() {
        //把播放列表顺序翻转
        List<Track> playList = mPlayerManager.getPlayList();
        Collections.reverse(playList);
        mIsReverse = !mIsReverse;
        //第一个参数是播放列表，第二个参数是开始播放的下标
        mCurrentIndex = playList.size() - 1 - mCurrentIndex;//新的下标 = 总的内容个数 - 1 - 当前的下标
        mPlayerManager.setPlayList(playList,mCurrentIndex);
        mCurrentTrack = (Track) mPlayerManager.getCurrSound();
        //更新UI
        if (mIPlayerViewCallbacks != null) {
            for (IPlayerViewCallback iPlayerViewCallback : mIPlayerViewCallbacks) {
                iPlayerViewCallback.onListLoaded(playList);
                iPlayerViewCallback.onTrackUpdate(mCurrentTrack,mCurrentIndex);
                iPlayerViewCallback.updateListOrder(mIsReverse);
            }
        }
    }

    @Override
    public boolean hasPlayList() {
        return isSetPlayListData;
    }

    @Override
    public void playByAlbumId(long id) {
        //1.要获取到专辑的列表内容
        XimalayApi ximalayApi = XimalayApi.getXimalayApi();
        ximalayApi.getDetailList(new IDataCallBack<TrackList>() {
            @Override
            public void onSuccess(TrackList trackList) {
                //2.把专辑内容设置给播放器
                List<Track> tracks = trackList.getTracks();
                if (trackList != null&&tracks.size()>0) {
                    mPlayerManager.setPlayList(tracks,DEFAULT_PLAY_INDEX);
                    isSetPlayListData = true;
                    mCurrentTrack = tracks.get(DEFAULT_PLAY_INDEX);
                    mCurrentIndex = DEFAULT_PLAY_INDEX;
                }

            }

            @Override
            public void onError(int i, String s) {
                Toast.makeText(getAppContext(),"请求数据错误",Toast.LENGTH_SHORT).show();
            }
        },(int)id,1);

        //3.播放了
    }

    @Override
    public void registerViewCallback(IPlayerViewCallback iPlayerViewCallback) {
        if (mIPlayerViewCallbacks != null&&!mIPlayerViewCallbacks.contains(iPlayerViewCallback)) {
            mIPlayerViewCallbacks.add(iPlayerViewCallback);
            //更新之前，让UI的Pager有数据
            getPlayListData();
            //通知当前的节目
            iPlayerViewCallback.onTrackUpdate(mCurrentTrack,mCurrentIndex);
            iPlayerViewCallback.onProgressChange(mCurrentProgressPosition,mCurrentProgressDuration);
            //更新播放状态
            handlePlayState(iPlayerViewCallback);
            //从sp里头拿当前播放模式
            int modeIndex = mPlayModeSp.getInt(PLAY_MODE_SP_KEY,PLAY_MODEL_LIST_LOOP_INT);
            mCurrentPlayMode = getModeByInt(modeIndex);
            iPlayerViewCallback.onPlayModeChange(mCurrentPlayMode);

        }
    }

    private void handlePlayState(IPlayerViewCallback iPlayerViewCallback) {
        int playerStatus = mPlayerManager.getPlayerStatus();
        //根据状态调用接口的方法
        if (PlayerConstants.STATE_STARTED==playerStatus) {
            iPlayerViewCallback.onPlayStart();
        }else {
            iPlayerViewCallback.onPlayPause();
        }
    }

    @Override
    public void unRegisterViewCallback(IPlayerViewCallback iPlayerViewCallback) {
        if (mIPlayerViewCallbacks != null) {
            mIPlayerViewCallbacks.remove(iPlayerViewCallback);
        }
    }









    /**
     * 广告状态监听器内部类
     */
    private class MyIXmAdsStatusListener implements IXmAdsStatusListener {
        @Override
        public void onStartGetAdsInfo() {
            UtilLog.d(TAG,"开始获取广告物料...");
        }

        @Override
        public void onGetAdsInfo(AdvertisList advertisList) {
            UtilLog.d(TAG,"获取广告物料成功...");

        }

        @Override
        public void onAdsStartBuffering() {
            UtilLog.d(TAG,"广告开始缓冲...");

        }

        @Override
        public void onAdsStopBuffering() {
            UtilLog.d(TAG,"广告结束缓冲...");

        }

        /**
         * @param advertis 当前播放广告
         * @param i 当前播放的广告在广告列表中的索引
         */
        @Override
        public void onStartPlayAds(Advertis advertis, int i) {
            UtilLog.d(TAG,"开始播放广告...");
            Toast.makeText(getAppContext(), "正在播放广告", Toast.LENGTH_LONG).show();
        }

        @Override
        public void onCompletePlayAds() {
            UtilLog.d(TAG,"广告播放完毕...");

        }

        /**
         * @param what 错误类型
         * @param extra 错误的额外信息
         */
        @Override
        public void onError(int what, int extra) {
            UtilLog.d(TAG,"播放广告错误...");
            UtilLog.d(TAG,"错误类型 ==> "+what);
            UtilLog.d(TAG,"错误的额外信息 ==> "+extra);

        }
    }





    /**
     * 播放器状态监听器内部类
     */
    private class MyIXmPlayerStatusListener implements IXmPlayerStatusListener{
        @Override
        public void onPlayStart() {
            UtilLog.d(TAG,"开始播放...");
            if (mIPlayerViewCallbacks != null) {
                for (IPlayerViewCallback iPlayerViewCallback : mIPlayerViewCallbacks) {
                    iPlayerViewCallback.onPlayStart();
                }
            }
        }

        @Override
        public void onPlayPause() {
            UtilLog.d(TAG,"暂停播放...");
            if (mIPlayerViewCallbacks != null) {
                for (IPlayerViewCallback iPlayerViewCallback : mIPlayerViewCallbacks) {
                    iPlayerViewCallback.onPlayPause();
                }
            }

        }

        @Override
        public void onPlayStop() {
            UtilLog.d(TAG,"停止播放...");
            if (mIPlayerViewCallbacks != null) {
                for (IPlayerViewCallback iPlayerViewCallback : mIPlayerViewCallbacks) {
                    iPlayerViewCallback.onPlayStop();
                }
            }
        }

        @Override
        public void onSoundPlayComplete() {
            UtilLog.d(TAG,"播放完成...");

        }

        @Override
        public void onSoundPrepared() {
            UtilLog.d(TAG,"播放器准备完毕...");
            UtilLog.d(TAG,"播放器当前状态 ==> "+mPlayerManager.getPlayerStatus());
            if (mPlayerManager != null) {
                mPlayerManager.setPlayMode(mCurrentPlayMode);
                if (mPlayerManager.getPlayerStatus()== PlayerConstants.STATE_PREPARED) {
                    //播放器准备完了，可以去播放了
                    mPlayerManager.play();
                }
            }
        }

        /**
         * model中的kind字段来判断是track、radio和schedule；
         * @param lastModel 上一首model,可能为空
         * @param curModel 下一首model
         */
        @Override
        public void onSoundSwitch(PlayableModel lastModel, PlayableModel curModel) {
            UtilLog.d(TAG,"切歌...");
            if (lastModel != null) {
                UtilLog.d(TAG,"lastModel ==> "+lastModel.getKind());
            }
            if (curModel != null) {
                UtilLog.d(TAG,"curModel ==> "+curModel.getKind());
            }


            if (mPlayerManager != null) {
                mCurrentIndex = mPlayerManager.getCurrentIndex();
            }
            if (curModel instanceof Track) {
                Track currentTrack = (Track) curModel;
                mCurrentTrack = currentTrack;
                //保存播放记录
                HistoryPresenter historyPresenter = HistoryPresenter.getHistoryPresenter();
                historyPresenter.addHistory(currentTrack);
                UtilLog.d(TAG,"曲目标题是："+ mCurrentTrack.getTrackTitle());
                if (mIPlayerViewCallbacks != null) {
                    for (IPlayerViewCallback iPlayerViewCallback : mIPlayerViewCallbacks) {
                        iPlayerViewCallback.onTrackUpdate(mCurrentTrack,mCurrentIndex);
                    }
                }
            }


        }

        @Override
        public void onBufferingStart() {
            UtilLog.d(TAG,"开始缓冲...");

        }

        @Override
        public void onBufferingStop() {
            UtilLog.d(TAG,"结束缓冲...");

        }

        @Override
        public void onBufferProgress(int progress) {
            UtilLog.d(TAG,"缓冲进度回调 ==> "+progress);

        }

        /**
         * @param currPos 当前进度，单位是毫秒
         * @param duration 总共时长，单位是毫秒
         */
        @Override
        public void onPlayProgress(int currPos, int duration) {
            mCurrentProgressPosition = currPos;
            mCurrentProgressDuration = duration;
            UtilLog.d(TAG,"播放进度回调..."+"当前进度 ==> "+currPos+"   总共时长 ==> "+duration);
            if (mIPlayerViewCallbacks != null) {
                for (IPlayerViewCallback iPlayerViewCallback : mIPlayerViewCallbacks) {
                    iPlayerViewCallback.onProgressChange(currPos,duration);
                }
            }
        }

        @Override
        public boolean onError(XmPlayerException e) {
            UtilLog.d(TAG,"播放器错误 => "+e);
            Toast.makeText(getAppContext(),"播放器错误",Toast.LENGTH_SHORT).show();
            return false;
        }
    }
}
